package controller;

import java.awt.event.*;
import javax.swing.*;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;

import view.*;
import view.dialog.CameraViewDialog;
import view.dialog.RoomInfoDialog;
import model.*;

/**
 * Represents the controller that binds the system's data and
 * GUI and processes user input.   
 * @author Kenny Chong, Dan End, James Ju
 * CSE 333 : User Interface
 * Project HMSystem
 */
public class HMSController {

	// Variables.
	private HMSView view;
	private HMSModel model;
	
	private boolean done;
	
	/**
	 * Constructor.
	 * @param model
	 * @param view
	 */
	public HMSController(HMSModel model, HMSView view)
	{
		// Initialize values.
		this.view = view;
		this.model = model;
		
		// Add window listener.
		view.addWindowListener(new WindowListener());
		
		// Register login events.
		this.regLoginSpaceEvents();
		
		done = false;
	}
	
	/**
	 * Register components for work space events.
	 */
	public void regWorkSpaceEvents()
	{	
		view.addActionListenerDepartment(new department());
		view.addActionListenerAboutUs(new aboutUs());
		view.addActionListenerBudget(new budget());
		view.addActionListenerEmployee(new employee());
		view.addActionListenerGetHelp(new getHelp());
		view.addActionListenerLog(new log());
		view.addActionListenerPreference(new preference());
		view.addActionListenerRecentMsgs(new recentmsg());
		view.addActionListenerLogOut(new logout());
		view.addActionListenerFloor(new floor());
		view.addActionListenerHome(new home());
		
		// For floor panel.
		FloorPanel panel = (FloorPanel)view.getWorkSpacePanel().getCurrentPanel("floorPanel");
		panel.addCameraListener(new ViewCameraListener());
		panel.addSearchGuestListener(new SearchGuestListener());
		panel.addHighLightChangeListener(new HighLightListener());
	}
	
	/**
	 * Register components for events for logging in.
	 */
	public void regLoginSpaceEvents()
	{
		view.setHelpListener(new HelpAction("Help", null));
		view.setSubmitListener(new SubmitButtonListener());
		view.setExitListener(new ExitAction("Exit", null));
		view.setAboutListener(new AboutAction("About", null));
	}

	
	/**
	 * Used for login.
	 * @author Kenny
	 */
	class SubmitButtonListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			// Retrieve name.
			String userName = view.getLoginPanel().getUserName();
			// Retrieve password.
			char [] input = view.getLoginPanel().getPassName();
			
			// Verify user and password.
			if (model.vertifyUser(userName, input))
			{
				// Switch perspectives.
				view.setPanelSpace(PanelType.WORK);
				
				// Initialize workspace button listeners.
				HMSController.this.regWorkSpaceEvents();
			} else {
				// Display error message.
				JOptionPane.showMessageDialog(view,
						"Incorrect name or password, please try again.",
						"Incorrect Name Or Password!",
						JOptionPane.ERROR_MESSAGE);
			}
		}
	}
	
	/**
	 * Used for help message in login screen.
	 * @author Kenny
	 */
	class HelpAction extends AbstractAction
	{
		public HelpAction(String name, Icon icon)
		{
			putValue(Action.NAME, name);
			putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
			        KeyEvent.VK_H, ActionEvent.CTRL_MASK));
		}
		
		public void actionPerformed(ActionEvent e) 
		{
			// Display a help message.
			JOptionPane
					.showMessageDialog(
							view,
							"If you need assistance, " +
							"please call help desk at: (718)123-4731.\n" +
							"(Hint: Kenny, 1234x or James, Hello)",
							"Help", JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	class AboutAction extends AbstractAction
	{
		public AboutAction(String name, Icon icon)
		{
			putValue(Action.NAME, name);
			putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
			        KeyEvent.VK_A, ActionEvent.CTRL_MASK));
		}
		
		public void actionPerformed(ActionEvent e) 
		{
			// Display about message.
			JOptionPane
					.showMessageDialog(
							view,
							"CSE 333: User Interface Project Fall 2011\n"
									+ "By: Kenny Chong, James Ju, Dan End\n(GO GO POWER RANGERS!).",
							"About", JOptionPane.INFORMATION_MESSAGE);
		}
	}
	
	/**
	 * Used for exiting the program.
	 * @author Kenny
	 */
	class ExitAction extends AbstractAction
	{

		public ExitAction(String name, Icon icon)
		{
			putValue(Action.NAME, name);
			putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke(
			        KeyEvent.VK_E, ActionEvent.CTRL_MASK));
		}
		
		public void actionPerformed(ActionEvent e) 
		{
			// Display confirm message.
			int option = JOptionPane.showConfirmDialog(view, "Do you want to exit?", "Exit?", 
					JOptionPane.YES_NO_OPTION);
		
			// Yes option.
			if (option == 0)
			{
				// Exit System
				System.exit(0);
			} else {
				view.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
			}
		}
	}
	
	class WindowListener extends WindowAdapter
	{
		@Override
		public void windowClosing(WindowEvent e)
		{
			int option = JOptionPane.showConfirmDialog(view, "Do you want to exit?", "Exit?", 
					JOptionPane.YES_NO_OPTION);
		
			// Yes option.
			if (option == 0)
			{
				// Exit System
				view.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			} else {
				view.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
			}
		}
	}

	
	/**
	 * ActionListener for Departments JMenuItem
	 * @author shin
	 *
	 */
	class department implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("Departments Action Listern Test Success");
		}
	}
	/**
	 * ActionListener for Preference JMenuItem
	 * @author shin
	 *
	 */
	class preference implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("Preference Action Listern Test Success");
		}
	}
	/**
	 * ActionListener for Controller JMenuItem
	 * @author shin
	 *
	 */
	class controller implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("Controller Action Listern Test Success");
		}
	}
	/**
	 * ActionListener for Log JMenuItem
	 * @author shin
	 *
	 */
	class log implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("Log Action Listern Test Success");
		}
	}
	/**
	 * ActionListener for Recent Message JMenuItem
	 * @author shin
	 *
	 */
	class recentmsg implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			view.getWorkSpacePanel().setPanel("messagePanel");			
		}
	}

	/**
	 * ActionListener for LogOut JMenuItem
	 * @author shin
	 *
	 */
	class logout implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			// Confirm user that he or she wants to log out.
			int option = JOptionPane.showConfirmDialog(view,
					"Are you sure you want to logout?", "Logout?",
					JOptionPane.YES_NO_OPTION);
			
			if (option == JOptionPane.YES_OPTION)
			{
				// Switch back to login perspective.
				view.setPanelSpace(PanelType.LOGIN);
			}
		}
	}
	/**
	 * ActionListener for Employee JMenuItem
	 * @author shin
	 *
	 */
	class employee implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			view.getWorkSpacePanel().setPanel("employeesPanel");			
		}
	}
	/**
	 * ActionListener for Budget JMenuItem
	 * @author shin
	 *
	 */
	class budget implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			view.getWorkSpacePanel().setPanel("budgetPanel");
		}
	}
	/**
	 * ActionListener for About Us JMenuItem
	 * @author shin
	 *
	 */
	class aboutUs implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("About Us Action Listern Test Success");
		}
	}
	/**
	 * ActionListener for Get Help JMenuItem
	 * @author shin
	 *
	 */
	class getHelp implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			System.out.println("GetHelp Action Listern Test Success");
		}
	}
	
	/**
	 * ActionListener for Floor JMenuItem
	 * @author shin
	 *
	 */
	class floor implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			// Set the panel.
			view.getWorkSpacePanel().setPanel("floorPanel");
			
			// Retrieve it for modification.
			FloorPanel panel = (FloorPanel) view.getWorkSpacePanel()
					.getCurrentPanel("floorPanel");
			
			// Retrieve floor.
			Floor floor = model.getCurrentFloor();
			
			// Draw rooms only once.
			if (done == false)
			{
				
				// Retrieve rooms.
				ArrayList<Room> roomList = floor.getRMList();
				
				// Draw the rooms.
				for (Room room : roomList)
				{
					int x = room.getXCoordinate();
					int y = room.getYCoordinate();
					
					int width = room.getRoomType().getWidth();
					int height = room.getRoomType().getHeight();
					
					JPanel rPanel =	panel.drawRoom(x, y, width, height, room.getRoomName());
					
					// Register rPanel with clientProperty.
					rPanel.putClientProperty("Room", room);
					
					// Register rPanel with FloorMouseListener.
					rPanel.addMouseListener(new FloorMouseListener());
					
					// Set tool tip for when user hovers over the panel.
					rPanel.setToolTipText("Occupied: " + room.isOccupied());
				}	
				done = true;
			}
		}
	}
	
	class FloorMouseListener extends MouseAdapter
	{	
		@Override
		public void mouseClicked(MouseEvent e)
		{
			
			if (e.getSource() instanceof JPanel)
			{
			// Retrieve roomPanel from source.
			JPanel roomPanel = (JPanel)e.getSource();
			
			// Retrieve room information.
			Room room = (Room)roomPanel.getClientProperty("Room");
			
			// room name.
			String rmName = room.getRoomName();
			// room type.
			String rmType = "" + room.getRoomType();
			// room cleaned.
			String rmClean = "" + room.isCleaned();
			// room occupied.
			String rmOccupied = "" + room.isOccupied();
			
			// Open up dialog box.
			RoomInfoDialog dialog = new RoomInfoDialog(rmName, rmType,
						rmOccupied, rmClean, room.getGuestList());
			
			dialog.open();
			}
		}
	}
	
	/**
	 * ActionListener for Floor JMenuItem
	 * @author shin
	 *
	 */
	class home implements ActionListener
	{
		public void actionPerformed(ActionEvent arg0)
		{
			view.getWorkSpacePanel().setPanel("homepagePanel");
		}
	}
	
	/**
	 * ActionListener for viewing camera in floor view.
	 */
	class ViewCameraListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
			// Open CameraViewDialog.
			CameraViewDialog cdialog = new CameraViewDialog(); 
			
			cdialog.open();
		}
	}
	
	/**
	 * ActionListener for searching for guests in floor view.
	 */
	class SearchGuestListener implements ActionListener
	{
		public void actionPerformed(ActionEvent e)
		{
		
		// Retrieve text field input.
		FloorPanel panel = (FloorPanel)view.getWorkSpacePanel().getCurrentPanel("floorPanel");
			
		String guestName = panel.getTextField().getText();
		
		// Search for the guest.
		Guests guest = model.getCurrentFloor().searchForGuest(guestName);
		
		// Display results
		if (guest != null)
		{
			String roomName = guest.getCurrentRoom().getRoomName();

				JOptionPane.showMessageDialog(view, guest.getName() + " is at "
						+ roomName + ".", "Results",
						JOptionPane.INFORMATION_MESSAGE);
			} else {
				JOptionPane.showMessageDialog(view, "Guest cannot be found.",
						"Result", JOptionPane.INFORMATION_MESSAGE);
			}
		}
	}
	
	class HighLightListener implements ItemListener
	{

		@Override
		public void itemStateChanged(ItemEvent arg0) 
		{
			if (arg0.getStateChange() == ItemEvent.SELECTED)
			{
				// Retrieve Source.
				JComboBox type = (JComboBox)arg0.getSource();
				
				String value = (String)type.getSelectedItem();
				
				if (value.equals("None"))
				{
					
				} else if (value.equals("Occupied")) {
					
				} else if (value.equals("Cleaned")) {
					
				}
			}	
		}
		
	}
}
